home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 23 code / Internet Config / IC 1.1 / ICProgKit1.1 / Source / ICRandomSignature / ICSpecificOverride.p next >
Encoding:
Text File  |  1995-05-01  |  11.4 KB  |  368 lines  |  [TEXT/PJMM]

  1. unit ICSpecificOverride;
  2.  
  3. (* Internet Config Specific Overide Component *)
  4.  
  5. (* Routine names have an ICSO prefix for Internet Config Specific Override. *)
  6.  
  7. (* To create an IC override component you need to make a copy of this *)
  8. (* file and fill in the blanks. This is an N stage process: *)
  9.  
  10. (*  1. Make a copy of this file. *)
  11. (*  2. Change kOurComponentManufacturer to your manufacturer code. *)
  12. (*  3. Add any shared globals to the sharedGlobals record. *)
  13. (*  4. If you have shared globals then init them in ICSOInitShared. *)
  14. (*  5. If the shared globals need cleaning up then clean them ICSOCleanShared. *)
  15. (*  6. Add any instance specific globals to globalsRecord. *)
  16. (*  7. If you have globals then init them in ICSOInitGlobals. *)
  17. (*  8. If the globals need cleaning up then clean them ICSOCleanGlobals. *)
  18. (*  9. If you want to add a completely new routine or remove support *)
  19. (*     for one of the built in routines then modify ICSOCanDo accordingly. *)
  20. (* 10. Modify ICSOWhatToOverride to return the correct ProcPtr for each *)
  21. (*     routine that you override or add. *)
  22. (* 11. Write each routine. If you want the component to continue calling *)
  23. (*     through to the captured component for this routine then have your *)
  24. (*     routine return delegateThisCallErr. *)
  25. (* 12. Smirk at the wonders of Component Manager. *)
  26. (* 13. Looking inside ICGenericOverride and frown at the wonders of Component Manager. *)
  27.  
  28. (* Share and Enjoy. *)
  29.  
  30. (* Quinn *)
  31. (* 12 Feb 1995 *)
  32.  
  33. interface
  34.  
  35.     uses
  36.         Components;
  37.  
  38.     const
  39.         kOurComponentManufacturer = 'JMJ ';
  40. (* You must set this up appropriately. Things will not be good otherwise. *)
  41.  
  42.         delegateThisCallErr = $81234568;
  43. (* Return this from a component routine if you want the generic override *)
  44. (* component to pass this call through to the captured component. *)
  45.  
  46.     type
  47.         sharedGlobals = record
  48.                 delegate: Component;
  49.                 (* add your own shared globals here *)
  50.             end;
  51.         sharedGlobalsPtr = ^sharedGlobals;
  52.  
  53.         globalsRecord = record
  54.                 self: ComponentInstance;
  55.                 target: ComponentInstance;
  56.                 delegate: ComponentInstance;
  57.                 shared: sharedGlobalsPtr;
  58.                 (* add your own component specific globals here*)
  59.                 current_signature: Handle;
  60.                 default_signature: Handle;
  61.                 sig_folder_name: Str63;
  62.                 random_seed: longint;
  63.             end;
  64.         globalsPtr = ^globalsRecord;
  65.         globalsHandle = ^globalsPtr;
  66.  
  67. (* Except when otherwise noted the globals handle is *)
  68. (* locked when any of these routines are called. *)
  69.  
  70.     function ICSOInitShared (globals: globalsHandle): ComponentResult;
  71. (* This routine is called to init the shared globals. *)
  72. (* If you return an error then you should make sure your part of *)
  73. (* the shared globals are 'clean'. *)
  74.  
  75.     function ICSOCleanShared (globals: globalsHandle): ComponentResult;
  76. (* This routine is called to clean the shared globals. *)
  77. (* WARNING:  This will never been called if you're using an old version *)
  78. (* of the Component Manager. Workaround: If your specifics only bleeds *)
  79. (* small amounts of memory then don't worry. If your specifics bleeds a *)
  80. (* lot of memory or other resources (such as open files) then refuse to *)
  81. (* install with older Component Managers (I think it was fixed in v2 of the *)
  82. (* manager. *)
  83.  
  84.     function ICSOInitGlobals (globals: globalsHandle): ComponentResult;
  85. (* This routine inits the override specific fields of the component *)
  86. (* specific globals. If it returns an error then the globals must be 'clean'. *)
  87.  
  88.     function ICSOCleanGlobals (globals: globalsHandle): ComponentResult;
  89. (* This routine cleans up the component specific globals, disposing any *)
  90. (* pointers and otherwise releasing any allocated resources. *)
  91.  
  92.     function ICSOCanDo (globals: globalsHandle; selector: integer): ComponentResult;
  93. (* This routine is called in response to a component can do request. *)
  94. (* You should set component result to: *)
  95. (*   -1 if you definitely want to say that the component can't do this *)
  96. (*     0 if you definitely want to say that the component can do this *)
  97. (*     1 if you want to let the target decide *)
  98. (* WARNING: These constants are quite different from the constants *)
  99. (* used by a standard Component Manager CanDo request. *)
  100.  
  101.     function ICSOWhatToOverride (globals: globalsHandle; selector: integer): ProcPtr;
  102. (* Return nil if you do not want to override this what. *)
  103. (* Return a pointer to a procedure with the appropriate signature *)
  104. (* if you do. *)
  105. (* WARNING: globals will not necessarily be locked and may be nil!!! *)
  106.  
  107. implementation
  108.  
  109.     uses
  110.         Folders, QuickDrawRules, ICTypes, ICCAPI, ICKeys, ICComponentSelectors;
  111.  
  112.     function ICSOInitShared (globals: globalsHandle): ComponentResult;
  113.     begin
  114.         ICSOInitShared := noErr;
  115.     end; (* ICSOInitShared *)
  116.  
  117.     function ICSOCleanShared (globals: globalsHandle): ComponentResult;
  118.     begin
  119.         ICSOCleanShared := noErr;
  120.     end; (* ICSOCleanShared *)
  121.  
  122.     function ICSOInitGlobals (globals: globalsHandle): ComponentResult;
  123.         var
  124.             err: ComponentResult;
  125.             refnum: integer;
  126.             strh: StringHandle;
  127.             junk: OSErr;
  128.     begin
  129.         globals^^.random_seed := TickCount;
  130.         globals^^.current_signature := nil;
  131.         globals^^.default_signature := nil;
  132.         err := noErr;
  133.         refnum := OpenComponentResFile(Component(globals^^.self));
  134.         if refnum <= 0 then begin
  135.             err := resNotFound;
  136.         end; (* if *)
  137.         if err = noErr then begin
  138.             strh := GetString(130);
  139.             if strh = nil then begin
  140.                 err := resNotFound;
  141.             end
  142.             else begin
  143.                 globals^^.sig_folder_name := strh^^;
  144.             end; (* if *)
  145.             if err = noErr then begin
  146.                 globals^^.default_signature := Get1Resource('TEXT', 128);
  147.                 if globals^^.default_signature = nil then begin
  148.                     err := resNotFound;
  149.                 end
  150.                 else begin
  151.                     DetachResource(globals^^.default_signature);
  152.                 end; (* if *)
  153.             end; (* if *)
  154.             junk := CloseComponentResFile(refnum);
  155.         end; (* if *)
  156.         ICSOInitGlobals := err;
  157.     end; (* ICSOInitGlobals *)
  158.  
  159.     function ICSOCleanGlobals (globals: globalsHandle): ComponentResult;
  160.     begin
  161.         if globals^^.current_signature <> nil then begin
  162.             DisposeHandle(globals^^.current_signature);
  163.             globals^^.current_signature := nil;
  164.         end; (* if *)
  165.         if globals^^.default_signature <> nil then begin
  166.             DisposeHandle(globals^^.default_signature);
  167.             globals^^.default_signature := nil;
  168.         end; (* if *)
  169.         ICSOCleanGlobals := noErr;
  170.     end; (* ICSOCleanGlobals *)
  171.  
  172.     function SneakyRandom (globals: globalsHandle): integer;
  173.         (* Get a random number without disturbing the random sequence in use *)
  174.         (* by the current application. *)
  175.         var
  176.             tmp: longint;
  177.     begin
  178.         tmp := QDGlobals^.randSeed;
  179.         QDGlobals^.randSeed := globals^^.random_seed;
  180.         SneakyRandom := Random;
  181.         globals^^.random_seed := QDGlobals^.randSeed;
  182.         QDGlobals^.randSeed := tmp;
  183.     end; (* SneakyRandom *)
  184.  
  185.     procedure ChooseRandomSignature (globals: globalsHandle);
  186.         var
  187.             cpb: CInfoPBRec;
  188.             sig: FSSpec;
  189.  
  190.         function GetNthTextFile (max_count: integer; var count: integer): OSErr;
  191.             var
  192.                 err: OSErr;
  193.                 index: integer;
  194.         begin
  195.             count := 0;
  196.             index := 1;
  197.             repeat
  198.                 cpb.ioNamePtr := @sig.name;
  199.                 cpb.ioDirID := sig.parID;
  200.                 cpb.ioVRefNum := sig.vRefNum;
  201.                 cpb.ioFDirIndex := index;
  202.                 err := PBGetCatInfoSync(@cpb);
  203.                 index := index + 1;
  204.                 if (err = noErr) and not btst(cpb.ioFlAttrib, 4) and (cpb.ioFlFndrInfo.fdType = 'TEXT') then begin
  205.                     count := count + 1;
  206.                 end; (* if *)
  207.             until (err <> noErr) or (count = max_count);
  208.             GetNthTextFile := err;
  209.         end; (* GetNthTextFile *)
  210.  
  211.         var
  212.             junk: OSErr;
  213.             texth: Handle;
  214.             err: OSErr;
  215.             ref: integer;
  216.             count: integer;
  217.             length: longint;
  218.     begin
  219.         if globals^^.current_signature <> nil then begin
  220.             DisposeHandle(globals^^.current_signature);
  221.             globals^^.current_signature := nil;
  222.         end; (* if *)
  223.         texth := nil;
  224.         sig.name := globals^^.sig_folder_name;
  225.         err := FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, sig.vRefNum, sig.parID);
  226.         if err = noErr then begin
  227.             cpb.ioNamePtr := @sig.name;
  228.             cpb.ioVRefNum := sig.vRefNum;
  229.             cpb.ioDirID := sig.parID;
  230.             cpb.ioFDirIndex := 0;
  231.             err := PBGetCatInfoSync(@cpb);
  232.         end; (* if *)
  233.         if (err = noErr) and not btst(cpb.ioFlAttrib, 4) then begin
  234.             err := dirNFErr;
  235.         end; (* if *)
  236.         if err = noErr then begin
  237.             sig.parID := cpb.ioDirID;
  238.             junk := GetNthTextFile(32767, count);
  239.             if count = 0 then begin
  240.                 err := fnfErr;
  241.             end
  242.             else begin
  243.                 count := (abs(SneakyRandom(globals)) mod count) + 1;
  244.                 err := GetNthTextFile(count, junk);
  245.             end; (* if *)
  246.         end; (* if *)
  247.         if err = noErr then begin
  248.             err := HOpen(sig.vRefNum, sig.parID, sig.name, fsRdPerm, ref);
  249.         end; (* if *)
  250.         if err = noErr then begin
  251.             err := GetEOF(ref, length);
  252.             if err = noErr then begin
  253.                 if length > 4096 then begin
  254.                     length := 4096;
  255.                 end; (* if *)
  256.                 texth := NewHandle(length);
  257.                 err := MemError;
  258.             end; (* if *)
  259.             if err = noErr then begin
  260.                 err := FSRead(ref, length, texth^);
  261.             end; (* if *)
  262.             junk := FSClose(ref);
  263.         end; (* if *)
  264.         if err <> noErr then begin
  265.             DisposeHandle(texth);
  266.             texth := nil;
  267.         end; (* if *)
  268.         if texth = nil then begin
  269.             texth := globals^^.default_signature;
  270.             err := HandToHand(texth);
  271.             if err <> noErr then begin
  272.                 texth := nil;
  273.             end; (* if *)
  274.         end; (* if *)
  275.         globals^^.current_signature := texth;
  276.     end; (* ChooseRandomSignature *)
  277.  
  278.     function RSCBegin (globals: globalsHandle; perm: ICPerm): ICError;
  279.         var
  280.             err: ICError;
  281.     begin
  282.         ChooseRandomSignature(globals);
  283.         RSCBegin := delegateThisCallErr;
  284.     end; (* RSCBegin *)
  285.  
  286.     function RSCGetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  287.         var
  288.             tmpstr: Str255;
  289.             perm: icPerm;
  290.             max_size: longint;
  291.             err: ICError;
  292.     begin
  293.         if IUEqualString(key, kICSignature) = 0 then begin
  294.             (* This is for compatibility with IC 1.0, which didn't call ICBegin/ICEnd through *)
  295.             (* the target when it was done automagically because of a ICGet/SetPref call. *)
  296.             (* So if there are no permissions then we know that we're in about to do *)
  297.             (* an automagic ICBegin so we randomise the signature. *)
  298.             if (ICCGetPerm(globals^^.delegate, perm) = noErr) & (perm = icNoPerm) then begin
  299.                 ChooseRandomSignature(globals);
  300.             end; (* if *)
  301.  
  302.             max_size := size;
  303.             if globals^^.current_signature = nil then begin
  304.                 size := 0;
  305.             end
  306.             else begin
  307.                 size := GetHandleSize(globals^^.current_signature);
  308.             end; (* if *)
  309.  
  310.             err := noErr;
  311.             if ((max_size < 0) and (buf <> nil)) then begin
  312.                 err := paramErr;
  313.             end; (* if *)
  314.             if (err = noErr) and (buf <> nil) then begin
  315.                 if size > max_size then begin
  316.                     err := icTruncatedErr;
  317.                 end
  318.                 else begin
  319.                     max_size := size;
  320.                 end; (* if *)
  321.                 if max_size <> 0 then begin
  322.                     BlockMove(globals^^.current_signature^, buf, max_size);
  323.                 end; (* if *)
  324.             end; (* if *)
  325.  
  326.             attr := ICattr_locked_mask + ICattr_volatile_mask;
  327.             RSCGetPref := err;
  328.         end
  329.         else begin
  330.             RSCGetPref := delegateThisCallErr;
  331.         end; (* if *)
  332.     end; (* RSCGetPref *)
  333.  
  334.     function RSCSetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  335.     begin
  336.         if IUEqualString(key, kICSignature) = 0 then begin
  337.             RSCSetPref := icPermErr;
  338.         end
  339.         else begin
  340.             RSCSetPref := delegateThisCallErr;
  341.         end; (* if *)
  342.     end; (* RSCSetPref *)
  343.  
  344.     function ICSOCanDo (globals: globalsHandle; selector: integer): ComponentResult;
  345.     begin
  346.         ICSOCanDo := delegateThisCallErr;
  347.     end; (* ICSOCanDo *)
  348.  
  349.     function ICSOWhatToOverride (globals: globalsHandle; selector: integer): ProcPtr;
  350.         var
  351.             proc: ProcPtr;
  352.     begin
  353.         proc := nil;
  354.         case selector of
  355.             kICCBegin: 
  356.                 proc := @RSCBegin;
  357.             kICCGetPref: 
  358.                 proc := @RSCGetPref;
  359.             kICCSetPref: 
  360.                 proc := @RSCSetPref;
  361.             otherwise
  362.                 ;
  363.         end; (* case *)
  364.         ICSOWhatToOverride := proc;
  365.     end; (* ICSOWhatToOverride *)
  366.  
  367. end. (* ICSpecificOverride *)
  368.